package org.shean.app.rssreader;

import java.text.ParseException;

import org.shean.app.rssreader.provider.SzRSSReader;
import org.shean.app.rssreader.utils.DateUtils;
import org.shean.app.rssreader.utils.RssUtils;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.content.AsyncQueryHandler;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;

public class PostListActivity extends ListActivity implements
		View.OnCreateContextMenuListener {

	private long mID;
	private PostListAdapter mAdapter;
	private Cursor mPostCursor;
	private boolean mAdapterSent;
	private long mCurrentSelectedID = -1;

	private boolean isTag = false;

	public static final int SET_ALL_READED_ID = Menu.FIRST;
	public static final int REFRESH_ID = Menu.FIRST + 1;
	public static final int DELETE_ALL_ID = Menu.FIRST + 2;

	public static final int DELETE_ID = Menu.FIRST + 3;
	public static final int SET_READED_ID = Menu.FIRST + 4;
	public static final int SET_UNREAD_ID = Menu.FIRST + 5;
	public static final int EDIT_COMMENT_ID = Menu.FIRST + 6;
	public static final int EDIT_TAG_ID = Menu.FIRST + 7;
	public static final int SEND_ID = Menu.FIRST + 8;
	
	public static final int REMOVE_ALL_ID = Menu.FIRST + 9;
	public static final int REMOVE_ID = Menu.FIRST + 10;

	@Override
	protected void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		setContentView(R.layout.post_picker_activity);

		mID = Long.parseLong(getIntent().getData().getPathSegments().get(1));

		if ("vnd.android.cursor.item/vnd.szrssreader.tag"
				.equals(getContentResolver().getType(getIntent().getData())))
			isTag = true;
		else
			isTag = false;

		ListView lv = getListView();
		lv.setFastScrollEnabled(true);
		lv.setOnCreateContextMenuListener(this);
		lv.setTextFilterEnabled(true);

		mAdapter = (PostListAdapter) getLastNonConfigurationInstance();
		if (mAdapter == null) {
			// Log.i("@@@", "starting query");
			mAdapter = new PostListAdapter(getApplication(), this,
					R.layout.post_list_item, mPostCursor, new String[] {},
					new int[] {});
			setListAdapter(mAdapter);
			setTitle(R.string.app_name);
			getPostCursor(mAdapter.getQueryHandler(), null);
		} else {
			mAdapter.setActivity(this);
			setListAdapter(mAdapter);
			mPostCursor = mAdapter.getCursor();
			if (mPostCursor != null) {
				init(mPostCursor);
			} else {
				getPostCursor(mAdapter.getQueryHandler(), null);
			}
		}
	}

	@Override
	public Object onRetainNonConfigurationInstance() {
		mAdapterSent = true;
		return mAdapter;
	}

	@Override
	public void onResume() {
		super.onResume();
		if (mPostCursor != null) {
			mPostCursor.requery();
		}
		getListView().invalidateViews();
	}

	@Override
	public void onDestroy() {
		if (!mAdapterSent) {
			Cursor c = mAdapter.getCursor();
			if (c != null) {
				c.close();
			}
		}
		super.onDestroy();
	}

	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		RssUtils.viewCurrentPost(this, mPostCursor, position, id, isTag);
	}

	@Override
	public void onPause() {
		mReScanHandler.removeCallbacksAndMessages(null);
		super.onPause();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);

		menu.add(0, SET_ALL_READED_ID, 0, "Set All Readed");
		// menu.add(0, REFRESH_ID, 1, "Refresh");
		menu.add(0, DELETE_ALL_ID, 2, "Delete All");
		menu.add(0, REMOVE_ALL_ID, 3, "Remove All");
		return true;
	}
	
	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		super.onPrepareOptionsMenu(menu);
		if (isTag) {
			menu.getItem(2).setVisible(true);
		} else {
			menu.getItem(2).setVisible(false);
		}
		
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case SET_ALL_READED_ID:
			Uri uri = SzRSSReader.Posts.CONTENT_URI;
			if (mID != -1) {
				uri = ContentUris.withAppendedId(
						SzRSSReader.Posts.CONTENT_URI_LIST, mID);
			}
			ContentValues values = new ContentValues();
			values.put(SzRSSReader.Posts.IS_READ, 1);

			if(isTag)
				getContentResolver().update(SzRSSReader.Posts.CONTENT_URI, values, getIDWhereSQL(), null);
			else
				getContentResolver().update(uri, values, null, null);

			getListView().invalidateViews();

			Intent intent = new Intent("org.shean.rssreader.POST_STATUSCHANGED");
			sendBroadcast(intent);
			return true;
		case DELETE_ALL_ID:
			showDialog(DELETE_ALL_ID);
			return true;
		case REMOVE_ALL_ID:
			getContentResolver().delete(SzRSSReader.PostTags.CONTENT_URI, SzRSSReader.PostTags.TAG_ID + "='" +mID +"'", null);
			mPostCursor.requery();
			getListView().invalidateViews();
			Intent intent3 = new Intent("org.shean.rssreader.POST_STATUSCHANGED");
			sendBroadcast(intent3);
			return true;
		}

		return super.onOptionsItemSelected(item);
	}

	private String getIDWhereSQL() {
		if (mPostCursor == null)
			return null;
		StringBuffer where = new StringBuffer();

		int len = mPostCursor.getCount();
		mPostCursor.moveToFirst();
		int colidx = mPostCursor.getColumnIndexOrThrow(SzRSSReader.Posts._ID);

		for (int i = 0; i < len - 1; i++) {
			where.append(SzRSSReader.Posts._ID + "='"
					+ mPostCursor.getInt(colidx) + "' AND ");
			mPostCursor.moveToNext();
		}

		where.append(SzRSSReader.Posts._ID + "='" + mPostCursor.getInt(colidx)
				+ "'");
		return where.toString();
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo info) {
		menu.setHeaderTitle("Post Menu");
		// menu.setHeaderIcon(R.drawable.feedicon);
		boolean is_readed = mPostCursor.getInt(mPostCursor
				.getColumnIndexOrThrow(SzRSSReader.Posts.IS_READ)) == 1;
		if (is_readed)
			menu.add(1, SET_UNREAD_ID, 0, "Set Unread");
		else
			menu.add(1, SET_READED_ID, 0, "Set Readed");

		menu.add(1, EDIT_COMMENT_ID, 0, "Edit Comment");
		menu.add(1, EDIT_TAG_ID, 0, "Edit Tag");
		
		if (isTag)
			menu.add(1, REMOVE_ID, 0, "Remove");
		//menu.add(1, SEND_ID, 0, "Send");
		menu.add(1, DELETE_ID, 0, "Delete");

	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {

		AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item
				.getMenuInfo();
		switch (item.getItemId()) {
		case SET_UNREAD_ID:
			Uri unread_uri = ContentUris.withAppendedId(
					SzRSSReader.Posts.CONTENT_URI, menuInfo.id);
			ContentValues values = new ContentValues();
			values.put(SzRSSReader.Posts.IS_READ, 0);
			getContentResolver().update(unread_uri, values, null, null);
			mPostCursor.requery();
			Intent intent = new Intent("org.shean.rssreader.POST_STATUSCHANGED");
			sendBroadcast(intent);
			return true;
		case SET_READED_ID:
			Uri read_uri = ContentUris.withAppendedId(
					SzRSSReader.Posts.CONTENT_URI, menuInfo.id);
			ContentValues read_values = new ContentValues();
			read_values.put(SzRSSReader.Posts.IS_READ, 1);
			getContentResolver().update(read_uri, read_values, null, null);
			mPostCursor.requery();
			Intent intent2 = new Intent(
					"org.shean.rssreader.POST_STATUSCHANGED");
			sendBroadcast(intent2);
			return true;
		case DELETE_ID:
			mCurrentSelectedID = menuInfo.id;
			showDialog(DELETE_ID);
			return true;
		case EDIT_TAG_ID:
			Uri tag_uri = ContentUris.withAppendedId(
					SzRSSReader.Posts.CONTENT_URI, menuInfo.id);
			Intent tag_intent = new Intent("android.intent.action.EDIT_TAG",
					tag_uri);
			startActivity(tag_intent);
			return true;
		case EDIT_COMMENT_ID:
			Uri comment_uri = ContentUris.withAppendedId(
					SzRSSReader.Posts.CONTENT_URI, menuInfo.id);
			Intent comment_intent = new Intent(
					"android.intent.action.EDIT_COMMENT", comment_uri);
			startActivity(comment_intent);
			return true;
		case REMOVE_ID:
			getContentResolver().delete(SzRSSReader.PostTags.CONTENT_URI, SzRSSReader.PostTags._ID + "='" +menuInfo.id +"'", null);
			mPostCursor.requery();
			getListView().invalidateViews();
			Intent intent3 = new Intent("org.shean.rssreader.POST_STATUSCHANGED");
			sendBroadcast(intent3);
			return true;

		}
		return super.onContextItemSelected(item);
	}

	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case DELETE_ID:
			return new AlertDialog.Builder(this).setIcon(
					R.drawable.alert_dialog_icon).setTitle("Delete Post")
					.setMessage("The post will be deleted.").setPositiveButton(
							"Ok", new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int whichButton) {

									if (mCurrentSelectedID > -1) {
										getContentResolver()
												.delete(
														SzRSSReader.Posts.CONTENT_URI,
														"_id=?",
														new String[] { String
																.valueOf(mCurrentSelectedID) });
										mPostCursor.requery();
										getListView().invalidateViews();

										Intent intent = new Intent(
												"org.shean.rssreader.POST_STATUSCHANGED");
										sendBroadcast(intent);
									}
									mCurrentSelectedID = -1;
								}
							}).setNegativeButton("Cancel",
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int whichButton) {
									mCurrentSelectedID = -1;
								}
							}).create();
		case DELETE_ALL_ID:
			return new AlertDialog.Builder(this).setIcon(
					R.drawable.alert_dialog_icon).setTitle("Delete Posts")
					.setMessage("All posts in this list will be deleted.")
					.setPositiveButton("Ok",
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int whichButton) {

									String where = null; // view all post
									if ("org.shean.rssreader.action.VIEW_UNREAD"
											.equals(getIntent().getAction())) {
										where = SzRSSReader.Posts.IS_READ
												+ "=0";
									} else if ("org.shean.rssreader.action.VIEW_FAVORITE"
											.equals(getIntent().getAction())) {
										where = SzRSSReader.Posts.IS_FAVORITE
												+ "=1";
									}

									if (mID != -1) {
										if (where == null)
											where = "channel_id='" + mID + "'";
										else
											where += " AND channel_id='" + mID
													+ "'";
									}
									
									if(isTag)
										where = getIDWhereSQL();

									getContentResolver().delete(
											SzRSSReader.Posts.CONTENT_URI,
											where, null);

									mPostCursor.requery();
									getListView().invalidateViews();

									Intent intent = new Intent(
											"org.shean.rssreader.POST_STATUSCHANGED");
									sendBroadcast(intent);

								}
							}).setNegativeButton("Cancel",
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int whichButton) {

								}
							}).create();
		}
		return null;
	}

	private Cursor getPostCursor(AsyncQueryHandler async, String filter) {

		Cursor ret = null;

		String[] cols = new String[] { SzRSSReader.Posts._ID,
				SzRSSReader.Posts.CHANNEL_ID, SzRSSReader.Posts.TITLE,
				SzRSSReader.Posts.IS_READ, SzRSSReader.Posts.POST_DATE,
				SzRSSReader.Posts.IS_FAVORITE };
		if(isTag)
			cols = new String[] { SzRSSReader.Posts._ID,
				SzRSSReader.Posts.CHANNEL_ID, SzRSSReader.Posts.TITLE,
				SzRSSReader.Posts.IS_READ, SzRSSReader.Posts.POST_DATE,
				SzRSSReader.Posts.IS_FAVORITE, SzRSSReader.PostTags.POST_ID};
		

		Uri uri = getIntent().getData();

		if (mID == -1) {
			uri = SzRSSReader.Posts.CONTENT_URI;
		}

		String where = null; // view all post
		if ("org.shean.rssreader.action.VIEW_UNREAD".equals(getIntent()
				.getAction())) {
			where = SzRSSReader.Posts.IS_READ + "=0";
		} else if ("org.shean.rssreader.action.VIEW_FAVORITE"
				.equals(getIntent().getAction())) {
			where = SzRSSReader.Posts.IS_FAVORITE + "=1";
		}

		if (async != null) {
			async.startQuery(0, null, uri, cols, where, null, null);
		} else {
			ret = managedQuery(uri, cols, where, null, null);
		}
		return ret;
	}

	private Handler mReScanHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			getPostCursor(mAdapter.getQueryHandler(), null);
		}
	};

	public void init(Cursor c) {

		mAdapter.changeCursor(c); // also sets mArtistCursor

		if (mPostCursor == null) {

			closeContextMenu();
			mReScanHandler.sendEmptyMessageDelayed(0, 1000);
			return;
		}
	}

	static class PostListAdapter extends SimpleCursorAdapter {

		private AsyncQueryHandler mQueryHandler;
		private PostListActivity mActivity;
		private final BitmapDrawable mReadIcon;
		private final BitmapDrawable mUnreadIcon;
		private final Resources mResources;

		private int mTitleIdx;
		private int mDateIdx;
		private int mReadIdx;
		private int mIdIdx;
		private int mFavoriteIdx;
		private int mChannelIdIdx;

		private boolean mConstraintIsValid = false;
		private String mConstraint = null;

		class ViewHolder {
			TextView line1;
			TextView line2;
			ImageView favorite;
			
			// ImageView play_indicator;
			View chip;
			TextView time;
			// ProgressBar download_progress;
		}

		class QueryHandler extends AsyncQueryHandler {
			QueryHandler(ContentResolver res) {
				super(res);
			}

			@Override
			protected void onQueryComplete(int token, Object cookie,
					Cursor cursor) {
				// Log.i("@@@", "query complete");
				mActivity.init(cursor);
			}
		}

		public PostListAdapter(Context context,
				PostListActivity currentactivity, int layout, Cursor c,
				String[] from, int[] to) {
			super(context, layout, c, from, to);
			mActivity = currentactivity;
			mQueryHandler = new QueryHandler(context.getContentResolver());

			Resources r = context.getResources();

			Bitmap b = BitmapFactory.decodeResource(r, R.drawable.readed);
			mReadIcon = new BitmapDrawable(b);
			// no filter or dither, it's a lot faster and we can't tell the
			// difference
			mReadIcon.setFilterBitmap(false);
			mReadIcon.setDither(false);

			b = BitmapFactory.decodeResource(r, R.drawable.unread);
			mUnreadIcon = new BitmapDrawable(b);
			// no filter or dither, it's a lot faster and we can't tell the
			// difference
			mReadIcon.setFilterBitmap(false);
			mReadIcon.setDither(false);

			getColumnIndices(c);
			mResources = context.getResources();
		}

		@Override
		public View newView(Context context, Cursor cursor, ViewGroup parent) {
			View v = super.newView(context, cursor, parent);
			ViewHolder vh = new ViewHolder();
			vh.line1 = (TextView) v.findViewById(R.id.line1);
			vh.line2 = (TextView) v.findViewById(R.id.line2);
			vh.favorite = (ImageView) v.findViewById(R.id.favorite);
			// vh.play_indicator = (ImageView)
			// v.findViewById(R.id.play_indicator);
			vh.chip = v.findViewById(R.id.chip);
			vh.time = (TextView) v.findViewById(R.id.time);
			// vh.icon.setBackgroundDrawable(mDefaultIcon);
			// vh.icon.setPadding(0, 0, 1, 0);
			// vh.download_progress = (ProgressBar) v
			// .findViewById(R.id.download_progress);
			vh.favorite.setOnTouchListener(new MyTouchListener());
			v.setTag(vh);
			return v;
		}

		private void getColumnIndices(Cursor cursor) {

			if (cursor != null) {

				mTitleIdx = cursor
						.getColumnIndexOrThrow(SzRSSReader.Posts.TITLE);
				mDateIdx = cursor
						.getColumnIndexOrThrow(SzRSSReader.Posts.POST_DATE);
				mReadIdx = cursor
						.getColumnIndexOrThrow(SzRSSReader.Posts.IS_READ);
				mIdIdx = cursor.getColumnIndexOrThrow(SzRSSReader.Posts._ID);
				mFavoriteIdx = cursor
						.getColumnIndexOrThrow(SzRSSReader.Posts.IS_FAVORITE);
				mChannelIdIdx = cursor.getColumnIndexOrThrow(SzRSSReader.Posts.CHANNEL_ID);
			}

		}

		@Override
		public void bindView(View view, Context context, Cursor cursor) {
			ViewHolder vh = (ViewHolder) view.getTag();

			String name = cursor.getString(mTitleIdx);
			vh.line1.setText(name);

			String datestr = cursor.getString(mDateIdx);
			try {
				name = DateUtils.formatDate(datestr);
				vh.time.setText(name);
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			// ImageView iv = vh.icon;
			int readed = cursor.getInt(mReadIdx);
			vh.chip.getBackground().setAlpha(readed == 1 ? 0 : 255);
			vh.line1.setTypeface(null, readed == 1 ? Typeface.NORMAL
					: Typeface.BOLD_ITALIC);
			// vh.duration.setVisibility(View.GONE);
			// vh.duration.setText("unread");
			FavoriteInfo favorite = new FavoriteInfo();
			favorite.id = cursor.getInt(mIdIdx);
			favorite.is_favorite = (cursor.getInt(mFavoriteIdx) == 1);

			vh.favorite.setTag(favorite);

			if (favorite.is_favorite)
				vh.favorite.setImageResource(R.drawable.btn_star_big_on);
			else
				vh.favorite.setImageResource(R.drawable.btn_star_big_off);
			
			if(mActivity.mID ==  -1 || mActivity.isTag)
			{
				Uri uri = ContentUris.withAppendedId(
						SzRSSReader.Channels.CONTENT_URI, cursor.getLong(mChannelIdIdx));
				Cursor channel = context.getContentResolver().query(uri, new String[]{SzRSSReader.Channels.TITLE}, 
						null, null, null);
				String channel_title = "";
				if(channel.moveToFirst())
					channel_title = channel.getString(channel.getColumnIndexOrThrow(SzRSSReader.Channels.TITLE));
				
				vh.line2.setText(channel_title);
				channel.close();
			}
			// vh.download_progress.setVisibility(View.GONE);

		}

		@Override
		public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
			String s = constraint.toString();
			if (mConstraintIsValid
					&& ((s == null && mConstraint == null) || (s != null && s
							.equals(mConstraint)))) {
				return getCursor();
			}
			Cursor c = mActivity.getPostCursor(null, s);
			mConstraint = s;
			mConstraintIsValid = true;
			return c;
		}

		public AsyncQueryHandler getQueryHandler() {
			return mQueryHandler;
		}

		public void setActivity(PostListActivity newactivity) {
			mActivity = newactivity;
		}

		@Override
		public void changeCursor(Cursor cursor) {
			if (cursor != mActivity.mPostCursor) {
				mActivity.mPostCursor = cursor;
				getColumnIndices(cursor);
				super.changeCursor(cursor);
			}
		}

		class MyTouchListener implements View.OnTouchListener {
			public boolean onTouch(View v, MotionEvent event) {
				// TODO Auto-generated method stub
				if (event.getAction() == MotionEvent.ACTION_UP) {
					FavoriteInfo fInfo = (FavoriteInfo) v.getTag();

					// ((ImageView)v).setImageResource(R.drawable.btn_star_big_off);
					ContentValues values = new ContentValues();
					values.put(SzRSSReader.Posts.IS_FAVORITE,
							fInfo.is_favorite ? 0 : 1);
					Uri uri = ContentUris.withAppendedId(
							SzRSSReader.Posts.CONTENT_URI, fInfo.id);
					mActivity.getContentResolver().update(uri, values, null,
							null);

					Intent intent = new Intent(
							"org.shean.rssreader.POST_STATUSCHANGED");
					mActivity.sendBroadcast(intent);
					mActivity.mPostCursor.requery();
					mActivity.getListView().invalidateViews();
				}
				return true;
			}

		}

		class FavoriteInfo {
			public int id;
			public boolean is_favorite;
		}

	}

}
